// SupportHanger.cpp: implementation of the SupportHanger class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SupportHanger.h"
#include "Part.h"
#include "phsapp.h"
#include <math.h>
#include "ModelVisitor.h"
#include "phsshare.h"
#include "SupportHangerIterator.h"

using namespace PersistentObjectOperation;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

UE_IMPLEMENT_VISITOR(SHVisitor);
UE_IMPLEMENT_DYNAMIC(SupportHanger, ModelObject);
SupportHanger::SupportHanger()
{
	m_bIsReadAll = TRUE;
	m_bIsCheckOut = TRUE;
}

SupportHanger::~SupportHanger()
{
	m_PropertyStack.RemoveAll();
	m_FunctionStack.RemoveAll();
}



/////////////////////////////////////////////////////////////////////////////
void SupportHanger::AddPart(Part* pPart)
{
	ASSERT(pPart);
	ASSERT(this->project());

	this->m_thePartManager.project(project());
	pPart->project(this->project());
	pPart->SupportHangerOwner(this);
	pPart->RegisterEffect();
	pPart->OwnerId(this->Id());
	m_thePartManager.AddPart(pPart);
}

void SupportHanger::AddJoint(Joint* pJoint)
{
	ASSERT(pJoint);
	ASSERT(this->project());

	this->m_theJointManager.project(project());
	pJoint->project(this->project());
	pJoint->SupportHangerOwner(this);
	pJoint->RegisterEffect();
	m_theJointManager.AddJoint(pJoint);
}

BOOL SupportHanger::Accept(PersistentObjectVisitor* pVisitor)
{
	ASSERT(pVisitor);
	void* p = pVisitor->QueryInterface(SHVisitor::RuntimeClass());
	if(p != NULL)
		return ((SHVisitor*)(p))->Visit((SupportHanger*)this);
	return TRUE;
}

BOOL SupportHanger::Accept(ModelVisitor* pVisitor)
{
	ASSERT(pVisitor);
	return pVisitor->Visit(*this);
}

void SupportHanger::SetDelete()
{
	if(this->IsDeleteState())
		return;

	PersistentObject::SetDelete();

	SupportHangerIterator* pIt = new SupportHangerIterator(this);
	ASSERT_MEMORY_VALID(pIt, NORETURN);
	for(pIt->Begin(); !pIt->End(); pIt->Next())
	{
		Part* pPart = pIt->Get();
		ASSERT(pPart);
		pPart->SetDelete();
	}
	delete pIt;
}

void SupportHanger::SetUndoDelete()
{
	if(!this->IsDeleteState())
		return;

	PersistentObject::SetUndoDelete();
	SupportHangerIterator* pIt = new SupportHangerIterator(this);
	ASSERT_MEMORY_VALID(pIt, NORETURN);
	for(pIt->Begin(); !pIt->End(); pIt->Next())
	{
		Part* pPart = pIt->Get();
		ASSERT(pPart);
		pPart->SetUndoDelete();
	}
	delete pIt;
}

ModelObject* SupportHanger::Clone()
{
	ASSERT(FALSE);
	return NULL;
}

Part* SupportHanger::FindPart(INT nPartIndex)
{
	return this->m_thePartManager.GetPart(nPartIndex);
}

void SupportHanger::SetCheckIn()
{
	m_bIsCheckOut = FALSE;
}

void SupportHanger::SetCheckOut()
{
	this->SetModify();
	m_bIsCheckOut = TRUE;
}

Part* SupportHanger::SupportHangerEntry()
{
	Part* pSHEntry = NULL;
	if(pSHEntry == NULL && !m_nEntryPartIndex.IsNull())
	{
		pSHEntry = m_thePartManager.GetPart(m_nEntryPartIndex);
	}
	return pSHEntry;
}

BOOL SupportHanger::IsAvailable() 
{
	SupportHangerIterator it(this);
	for(it.Begin(); !it.End(); it.Next())
	{
		Part* pPart = it.Get();
		ASSERT(pPart);

		if(!pPart->IsAvailable())
		{
			return FALSE;
		}
	}

	PartJoinManager::Iterator* pIt = GetJointManager().NewIterator();
	ASSERT_MEMORY_VALID(pIt, FALSE);
	for(pIt->Begin(); !pIt->End(); pIt->Next())
	{
		Joint* pJoint = pIt->Get();
		ASSERT(pJoint);

		if(pJoint->IsDeleteState())
			continue;

		if(!pJoint->IsAvailable())
		{
			delete pIt;
			return FALSE;
		}
	}
	delete pIt;
	return TRUE;
}

void SupportHanger::SetAvailable()
{
	ModelObject::SetAvailable();
}

void SupportHanger::SetUnavailable()
{
	ModelObject::SetUnavailable();
}